package com.duowei.diandan.adapter;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.duowei.diandan.R;
import com.duowei.diandan.bean.food.FoodImpl;
import com.duowei.diandan.bean.food.FoodItem;
import com.duowei.diandan.bean.food.Meal;
import com.duowei.diandan.bean.food.Single;
import com.duowei.diandan.bean.food.SingleAndMeals;
import com.duowei.diandan.bean.food.SingleGroup;
import com.duowei.diandan.callback.FoodItemCallback;
import com.duowei.diandan.constant.MenuItemType;
import com.duowei.diandan.constant.Settings;
import com.duowei.diandan.databinding.MenuHeaderItemBinding;
import com.duowei.diandan.databinding.MenuRecyclerItemBinding;
import com.duowei.diandan.util.FoodHelper;
import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinHelper;

import java.util.ArrayList;
import java.util.List;

/**
 * 菜单列表 Adapter
 */
public class MenuAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
    private static final String TAG = "MenuAdapter";

    public static final int TYPE_HEADER = 0;
    public static final int TYPE_ITEM = 1;

    private List<FoodItem> mList;
    private OnFoodItemClickListener mOnFoodItemClickListener;

    public MenuAdapter(List<FoodItem> list, OnFoodItemClickListener listener) {
        mList = list;
        mOnFoodItemClickListener = listener;
    }

    public void updateData(List<FoodItem> newList) {
        FoodItemCallback callback = new FoodItemCallback(mList, newList);
        mList = newList;
        DiffUtil.DiffResult result = DiffUtil.calculateDiff(callback);
        result.dispatchUpdatesTo(this);
    }

    @Override
    public int getItemViewType(int position) {
        FoodItem item = mList.get(position);
        return MenuItemType.TYPE_HEADER == item.getMenuItemType() ? TYPE_HEADER : TYPE_ITEM;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();

        if (viewType == TYPE_HEADER) {

            MenuHeaderItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(context),
                    R.layout.recycler_item_menu_header, parent, false);

            return new HeaderViewHolder(binding);
        } else {

            MenuRecyclerItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(
                    context), R.layout.recycler_item_menu, parent, false);

            return new ItemViewHolder(binding);
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        FoodItem item = mList.get(position);

        if (holder instanceof HeaderViewHolder) {
            HeaderViewHolder hvh = (HeaderViewHolder) holder;
            hvh.bind(item.getName());

        } else if (holder instanceof ItemViewHolder) {
            ItemViewHolder ivh = (ItemViewHolder) holder;

            MenuRecyclerItemBinding binding = ivh.mBinding;

            FoodHelper.setCoverImage(item.getImgNo(), binding.include.coverView);
            FoodHelper.setPrice(item, binding.include.priceDescView);
            binding.include.nameView.setText(item.getName());

            binding.getRoot().setOnClickListener(v -> {
                if (mOnFoodItemClickListener != null) {
                    mOnFoodItemClickListener.onFoodItemClick(item.getFood(), binding.include.coverView);
                }
            });

            // 标签显示
            if (Settings.MAIN_INTERFACE_SHOW_LABEL) {
                binding.include.tagLayout.removeAllViews();
                if (item.getFood() instanceof Single) {
                    Single single = (Single) item.getFood();
                    setSingleDiscounts(single, binding.include.tagLayout);

                } else if (item.getFood() instanceof SingleAndMeals) {
                    SingleAndMeals singleAndMeals = (SingleAndMeals) item.getFood();
                    setSingleDiscounts(singleAndMeals.getSingle(), binding.include.tagLayout);

                    List<Meal> mealList = singleAndMeals.getMealList();
                    if (mealList != null && mealList.size() > 0) {
                        addTagView(binding.include.tagLayout, "可选套餐");
                    }

                } else if (item.getFood() instanceof SingleGroup) {
                    addTagView(binding.include.tagLayout, "单品组");
                }
            }
        }
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public List<FoodItem> getList() {
        return mList;
    }

    public void setList(List<? extends FoodItem> list) {
        mList.clear();
        mList.addAll(list);
        notifyDataSetChanged();
    }

    private static void setSingleDiscounts(Single single, LinearLayout tagLayout) {
        if (single.getPresentList() != null && single.getPresentList().size() > 0) {
            addTagView(tagLayout, "买赠促销");
        }

        if (single.getAddPriceList() != null && single.getAddPriceList().size() > 0) {
            addTagView(tagLayout, "加价促销");
        }

        if (single.isHourDiscount()) {
            addTagView(tagLayout, "时段促销");
        }
    }

    private static void addTagView(LinearLayout layout, String tag) {
        TextView textView = (TextView) LayoutInflater.from(
                layout.getContext()).inflate(R.layout.layout_tag, layout, false);
        textView.setText(tag);

        layout.addView(textView);
    }

    public static class HeaderViewHolder extends RecyclerView.ViewHolder {
        MenuHeaderItemBinding mBinding;

        public HeaderViewHolder(MenuHeaderItemBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }

        public void bind(String title) {
            mBinding.setTitle(title);
            mBinding.executePendingBindings();
        }
    }

    public static class ItemViewHolder extends RecyclerView.ViewHolder {
        MenuRecyclerItemBinding mBinding;

        public ItemViewHolder(MenuRecyclerItemBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }
    }

    public interface OnFoodItemClickListener {
        void onFoodItemClick(FoodImpl food, ImageView iv);
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }

    private class ArrayFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            String searchText = constraint.toString();

            if (mOriginValues == null) {
                synchronized (mLock) {
                    mOriginValues = new ArrayList<>(mList);
                }
            }

            if (TextUtils.isEmpty(constraint)) {
                ArrayList<FoodItem> list;
                synchronized (mLock) {
                    list = new ArrayList<>(mOriginValues);
                }
                results.values = list;
                results.count = list.size();

            } else {
                ArrayList<FoodItem> values;
                synchronized (mLock) {
                    values = new ArrayList<>(mOriginValues);
                }

                ArrayList<FoodItem> newValues = new ArrayList<>();

                for (FoodItem i : values) {
                    try {
                        if (i.getName() != null
                                && MenuItemType.TYPE_ITEM == i.getMenuItemType()
                                && (i.getName().toLowerCase().contains(searchText.toLowerCase())
                                || PinyinHelper.getShortPinyin(i.getName()).toLowerCase().contains(searchText.toLowerCase()))) {
                            newValues.add(i);
                        }
                    } catch (PinyinException e) {
                        Log.e(TAG, "performFiltering: ", e);
                    }
                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            //noinspection unchecked
            mList = (List<FoodItem>) results.values;
            notifyDataSetChanged();
        }
    }

    private ArrayFilter mFilter;
    private final Object mLock = new Object();
    private ArrayList<FoodItem> mOriginValues;
}
